;	Tested; has bug:
;	Only certain rooms, when entered, are characters sync'd as soon as they enter

;	Position Sync Hack
;	If and only if warping is done, cause other players to spawn near player 1
;	when L is pressed and spawn them together when entering a new room

;	If 0x80011C4C == (instruction that's usually there)
;	Do 0x87 code type for enabling single player menu if and only if
;	mode is single player OR co-op warping has been done
.long				0xD2011C4C
ADDIU	V0,	V0,	0x0001	;Original code
.long				0x87011C4C
.long				0x00000000
;	AT, A0 and T7 are free
;	menuHackVars + RDRAM_START + TRAINER_OFFSET
;	has 16 bytes free contiguous with the rest of this hack
ADDIU	V0,	V0,	0x0001	;Original code

;	Quit if warping hasn't been done
LUI	AT,	%hi(warpingDone + RDRAM_START + TRAINER_OFFSET)
LW	AT,	%lo(warpingDone + RDRAM_START + TRAINER_OFFSET)	(AT)
LUI	A0,	0xDEAD		;
ORI	A0,	A0,	0xBEEF	;Warping done?
BNE	AT,	A0,		Position_Sync_Hack_Return
NOP

ADDIU	SP,	SP,	-0x0018	;Stack stuff
SW	S0,	0x0000	(SP)	;""
SW	S1,	0x0004	(SP)	;""
SW	S2,	0x0008	(SP)	;""
SW	S3,	0x000C	(SP)	;""
SW	S4,	0x0010	(SP)	;""
SW	S5,	0x0014	(SP)	;""

LUI	S0,	%hi(playerPointers + RDRAM_START + TRAINER_OFFSET)
ORI	S0,	S0,	%lo(playerPointers + RDRAM_START + TRAINER_OFFSET)
				;Pointers will be stored at [S0]
LW	S1,	0x004C	(T6)	;S1 = Pointer to a player's character's data + 0x7F0
ADDIU	S2,	R0,	-0x0001	;S2 = Uninitialized pointer
LUI	S4,	0x800A		;
LB	S4,	0x325D	(S4)	;[0x800A325D] (Player count)
OR	S3,	S4,	R0	;S3 = S4 = Player count

				Dump_Loop:
LW	S5,	0x0000	(S0)	;S5 = [S0]
BEQL	S5,	S2,		Dump
SW	S1,	0x0000	(S0)	;Pointer dumped
BEQ	S5,	S1,		Already_Dumped
NOP
ADDIU	S0,	S0,	0x0004	;
ADDIU	S3,	S3,	-0x0001	;
BNEZ	S3,			Dump_Loop
NOP

;	Loop expired; we have new pointers
LUI	S0,	%hi(playerPointers + RDRAM_START + TRAINER_OFFSET)
ORI	S0,	S0,	%lo(playerPointers + RDRAM_START + TRAINER_OFFSET)
SW	S1,	0x0000	(S0)	;First player?
SW	S2,	0x0004	(S0)	;Clear other pointers
SW	S2,	0x0008	(S0)	;""
BEQZ	R0,			Dump_Done
SW	S2,	0x000C	(S0)	;""

				Dump:
ADDIU	S3,	S3,	-0x0001	;
BEQZ	S3,			Synchronize
NOP
BEQZ	R0,			Dump_Done
NOP

				Already_Dumped:
LUI	S1,	0x8010		;
LH	S2,	0x5304	(S1)	;
XORI	S2,	S2,	0x0020	;Check L button; sync if only L pressed
BNEZ	S2,			Dump_Done
NOP
				Synchronize:
LUI	S0,	%hi(playerPointers + RDRAM_START + TRAINER_OFFSET)
ORI	S0,	%lo(playerPointers + RDRAM_START + TRAINER_OFFSET)
				;S0 points to player character pointer array
LW	S1,	0x0000	(S0)	;S1 points to player 1's character
ADDIU	S1,	S1,	-0x07F0	;S1 points to the beginning of the data
				;of player 1's character
ADDIU	S3,	S4,	-0x0001	;S3 is the player count minus 1
				;(the number of players to sync to player 1)

				Sync_Loop:
LW	S2,	0x0004	(S0)	;S2 points to the next player's character
ADDIU	S2,	S2,	-0x07F0	;S2 points to the beginning of the data
				;of the next player's character
LW	S5,	0x000C	(S1)	;
SW	S5,	0x000C	(S2)	;X sync'd
LW	S5,	0x0010	(S1)	;
SW	S5,	0x0010	(S2)	;Z sync'd
LW	S5,	0x0014	(S1)	;
SW	S5,	0x0014	(S2)	;Y sync'd
LH	S5,	0x01D8	(S1)	;
SH	S5,	0x01D8	(S2)	;Rotation sync'd
ADDIU	S0,	S0,	0x0004	;
ADDIU	S3,	S3,	-0x0001	;
BNEZ	S3,			Sync_Loop
NOP

				Dump_Done:
LW	S0,	0x0000	(SP)	;Stack stuff
LW	S1,	0x0004	(SP)	;""
LW	S2,	0x0008	(SP)	;""
LW	S3,	0x000C	(SP)	;""
LW	S4,	0x0010	(SP)	;""
LW	S5,	0x0014	(SP)	;""
ADDIU	SP,	SP,	0x0018	;""

				Position_Sync_Hack_Return:
J				0x00011C50
NOP
.align				3
.long				0xE0000000
.long				0x00000000
.long				0xE0000000
.long				0x00000000
;	End of Position Sync Hack
